home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 24
/
Amiga Format AFCD24 (Feb 1998, Issue 108).iso
/
-in_the_mag-
/
emulation
/
amiga
/
uae-0.7.0b2
/
src
/
gtkui.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-20
|
13KB
|
487 lines
/*
* UAE - the Un*x Amiga Emulator
*
* Yet Another User Interface for the X11 version
*
* Copyright 1997 Bernd Schmidt
*
* The Tk GUI doesn't work.
* The X Forms Library isn't available as source, and there aren't any
* binaries compiled against glibc
*
* So let's try this...
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include "config.h"
#include "options.h"
#include "uae.h"
#include "memory.h"
#include "custom.h"
#include "readcpu.h"
#include "gui.h"
#include "newcpu.h"
#include "threaddep/penguin.h"
#include <gtk/gtk.h>
static GtkWidget *disk_insert_widget[4], *disk_eject_widget[4], *disk_text_widget[4];
static char *led_bufs[5];
static int gcs_initialized = 0;
static char *disk_string[4];
static char *new_disk_string[4];
static GtkWidget *led_widgets[5];
static int nr_for_led (GtkWidget *led)
{
int i;
i = 0;
while (led_widgets[i] != led)
i++;
return i;
}
static smp_comm_pipe to_gui_pipe, from_gui_pipe;
static uae_sem_t gui_sem, gui_quit_sem;
static volatile int quit_gui = 0, quitted_gui = 0;
static void enable_disk_buttons (int enable);
static unsigned int prevledstate;
static void draw_led (int nr)
{
GtkWidget *thing = led_widgets[nr];
int r = 0, g = 0, b = 0;
int i, j, k;
char *buf = led_bufs[nr];
if (buf == 0)
return;
if (gui_ledstate & (1 << nr)) {
if (nr == 4)
r = 0xCC;
else
r = 0x88, g = 0xFF;
}
printf ("%dx%d\n", thing->allocation.width, thing->allocation.height);
for (j = k = 0; j < thing->allocation.width; j++)
buf[k++] = r, buf[k++] = g, buf[k++] = b;
for (i = 0; i < thing->allocation.height; i++) {
gtk_preview_draw_row (GTK_PREVIEW (thing), buf, 0, i, thing->allocation.width);
}
gtk_widget_draw (thing, 0);
}
static int my_idle (void)
{
unsigned int leds = gui_ledstate;
int i;
/*printf("...\n");*/
if (quit_gui) {
printf("Foo...\n");
gtk_main_quit ();
goto out;
}
while (comm_pipe_has_data (&to_gui_pipe)) {
int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
int n;
/*printf ("cmd %d\n", cmd);*/
switch (cmd) {
case 0:
n = read_comm_pipe_int_blocking (&to_gui_pipe);
gtk_label_set (GTK_LABEL (disk_text_widget[n]), currprefs.df[n]);
break;
}
}
for (i = 0; i < 5; i++) {
unsigned int mask = 1 << i;
GtkWidget *thing;
int on = leds & mask;
if (on == (prevledstate & mask))
continue;
printf(": %d %d\n", i, on);
draw_led (i);
}
prevledstate = leds;
out:
return 1;
}
static void did_reset (void)
{
if (quit_gui)
return;
write_comm_pipe_int (&from_gui_pipe, 2, 1);
}
static void did_debug (void)
{
if (quit_gui)
return;
write_comm_pipe_int (&from_gui_pipe, 3, 1);
}
static void did_quit (void)
{
if (quit_gui)
return;
write_comm_pipe_int (&from_gui_pipe, 4, 1);
}
static void did_eject (int n)
{
if (quit_gui)
return;
write_comm_pipe_int (&from_gui_pipe, 0, 0);
write_comm_pipe_int (&from_gui_pipe, n, 1);
}
static int filesel_active = -1;
static GtkWidget *selector;
static void did_close_insert (GtkObject *o, GtkWidget *w)
{
filesel_active = -1;
enable_disk_buttons (1);
}
static void did_cancel_insert (GtkObject *o)
{
did_close_insert (o, GTK_WIDGET (o));
gtk_widget_destroy (GTK_WIDGET (o));
}
static void did_insert_select (GtkObject *o)
{
char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (selector));
if (quit_gui)
return;
uae_sem_wait (&gui_sem);
if (new_disk_string[filesel_active] != 0)
free (new_disk_string[filesel_active]);
new_disk_string[filesel_active] = strdup (s);
uae_sem_post (&gui_sem);
write_comm_pipe_int (&from_gui_pipe, 1, 0);
write_comm_pipe_int (&from_gui_pipe, filesel_active, 1);
did_cancel_insert (o);
}
static void did_insert (int n)
{
char buffer[100];
if (filesel_active != -1)
return;
filesel_active = n;
enable_disk_buttons (0);
sprintf (buffer, "Select a disk image file for DF%d", n);
selector = gtk_file_selection_new (buffer);
gtk_signal_connect (GTK_OBJECT (selector), "destroy",
(GtkSignalFunc) did_close_insert, selector);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
"clicked", (GtkSignalFunc) did_insert_select,
GTK_OBJECT (selector));
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
"clicked", (GtkSignalFunc) did_cancel_insert,
GTK_OBJECT (selector));
printf("%p\n", selector);
gtk_widget_show (selector);
}
static void did_eject_0 (void) { did_eject (0); }
static void did_eject_1 (void) { did_eject (1); }
static void did_eject_2 (void) { did_eject (2); }
static void did_eject_3 (void) { did_eject (3); }
static void did_insert_0 (void) { did_insert (0); }
static void did_insert_1 (void) { did_insert (1); }
static void did_insert_2 (void) { did_insert (2); }
static void did_insert_3 (void) { did_insert (3); }
static void enable_disk_buttons (int enable)
{
int i;
for (i = 0; i < 4; i++) {
gtk_widget_set_sensitive (disk_insert_widget[i], enable);
gtk_widget_set_sensitive (disk_eject_widget[i], enable);
}
}
static gint driveled_event (GtkWidget *thing, GdkEvent *event)
{
gint x, y;
GtkStyle *style;
int lednr = nr_for_led (thing);
switch (event->type) {
case GDK_MAP:
draw_led (lednr);
break;
case GDK_EXPOSE:
if (led_bufs[lednr] == 0) {
printf ("- %d\n", thing->allocation.width);
led_bufs[lednr] = (char *)xmalloc (3 * thing->allocation.width);
draw_led (lednr);
}
break;
default:
break;
}
return 0;
}
static GtkWidget *make_led (int nr)
{
GtkWidget *subframe, *the_led, *thing;
the_led = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (the_led, 20, -1);
gtk_widget_show (the_led);
thing = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
gtk_widget_show (thing);
subframe = gtk_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (the_led), subframe, TRUE, TRUE, 0);
gtk_widget_show (subframe);
thing = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_container_add (GTK_CONTAINER (subframe), thing);
led_widgets[nr] = thing;
gtk_signal_connect (GTK_OBJECT (thing), "event",
(GtkSignalFunc) driveled_event, (gpointer) thing);
gtk_widget_show (thing);
thing = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
gtk_widget_show (thing);
return the_led;
}
static void *gtk_penguin (void *dummy)
{
GtkWidget *window;
GtkWidget *buttonbox, *vbox;
GtkWidget *thing;
int i;
int argc = 1;
char *a[] = {"UAE"};
char **argv = a;
gtk_init (&argc, &argv);
gtk_rc_parse ("uaegtkrc");
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name (window, "UAE control");
led_bufs[0] = led_bufs[1] = led_bufs[2] = led_bufs[3] = led_bufs[4] = 0;
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (window), vbox);
/* Make a box with the Reset/Debug/Quit buttons and place it at the top
* of our vbox. */
buttonbox = gtk_hbox_new (FALSE, 4);
thing = gtk_button_new_with_label ("Reset");
gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_reset, NULL);
gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
thing = gtk_button_new_with_label ("Debug");
gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_debug, NULL);
gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
thing = gtk_button_new_with_label ("Quit");
gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_quit, NULL);
gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
thing = make_led (4);
gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, TRUE, 0);
gtk_widget_show (buttonbox);
/* Place a separator below those three buttons. */
thing = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
/* Now, the floppy disk control. */
for (i = 0; i < 4; i++) {
GtkWidget *subthing, *subframe;
char buf[5];
sprintf (buf, "DF%d:", i);
/* Each line: a frame with a hbox in it. The hbox contains
* the LED, the name of the drive and the diskfile in it, an
* Insert button, and an Eject button. */
buttonbox = gtk_frame_new (buf);
thing = gtk_hbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (buttonbox), thing);
gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, TRUE, 0);
gtk_widget_show (buttonbox);
gtk_widget_show (thing);
buttonbox = thing;
subthing = make_led (i);
gtk_box_pack_start (GTK_BOX (buttonbox), subthing, FALSE, TRUE, 0);
/* Make the "DF0:xxx" label. */
subframe = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
gtk_box_pack_start (GTK_BOX (buttonbox), subframe, FALSE, TRUE, 0);
gtk_widget_show (subframe);
subthing = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (subframe), subthing);
gtk_widget_show (subthing);
/* First, an invisible preview widget to set the horizontal size. */
thing = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_widget_set_usize (thing, gdk_string_measure (subframe->style->font, "This is a very long name for a disk file, should be enough") + 7, 0);
gtk_widget_show (thing);
gtk_box_pack_start (GTK_BOX (subthing), thing, FALSE, TRUE, 0);
/* Then, a label with the filename. */
thing = gtk_label_new ("frebnisia");
disk_text_widget[i] = thing;
gtk_widget_show (thing);
gtk_box_pack_start (GTK_BOX (subthing), thing, FALSE, TRUE, 0);
/* Now, the buttons. */
thing = gtk_button_new_with_label ("Eject");
gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
disk_eject_widget[i] = thing;
gtk_signal_connect (GTK_OBJECT (thing), "clicked",
(GtkSignalFunc) (i == 0 ? did_eject_0
: i == 1 ? did_eject_1
: i == 2 ? did_eject_2 : did_eject_3),
NULL);
thing = gtk_button_new_with_label ("Insert");
gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
gtk_widget_show (thing);
disk_insert_widget[i] = thing;
gtk_signal_connect (GTK_OBJECT (thing), "clicked",
(GtkSignalFunc) (i == 0 ? did_insert_0
: i == 1 ? did_insert_1
: i == 2 ? did_insert_2 : did_insert_3),
NULL);
}
enable_disk_buttons (1);
gtk_widget_show (vbox);
gtk_widget_show (window);
gtk_timeout_add (1000, (GtkFunction)my_idle, 0);
gtk_main ();
quitted_gui = 1;
uae_sem_post (&gui_quit_sem);
return 0;
}
void gui_changesettings(void)
{
}
int gui_init(void)
{
penguin_id tid;
init_comm_pipe (&to_gui_pipe, 20, 1);
init_comm_pipe (&from_gui_pipe, 20, 1);
uae_sem_init (&gui_sem, 0, 1);
uae_sem_init (&gui_quit_sem, 0, 0);
start_penguin (gtk_penguin, NULL, &tid);
return 1;
}
int gui_update(void)
{
return 0;
}
void gui_exit(void)
{
quit_gui = 1;
uae_sem_wait (&gui_quit_sem);
}
void gui_led(int num, int on)
{
/* if (num == 0)
return;
printf("LED %d %d\n", num, on);
write_comm_pipe_int (&to_gui_pipe, 1, 0);
write_comm_pipe_int (&to_gui_pipe, num == 0 ? 4 : num - 1, 0);
write_comm_pipe_int (&to_gui_pipe, on, 1);
printf("#LED %d %d\n", num, on);
*/
}
void gui_filename(int num, const char *name)
{
write_comm_pipe_int (&to_gui_pipe, 0, 0);
write_comm_pipe_int (&to_gui_pipe, num, 1);
gui_update ();
}
void gui_handle_events(void)
{
while (comm_pipe_has_data (&from_gui_pipe)) {
int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
int n;
switch (cmd) {
case 0:
n = read_comm_pipe_int_blocking (&from_gui_pipe);
changed_prefs.df[n][0] = '\0';
break;
case 1:
n = read_comm_pipe_int_blocking (&from_gui_pipe);
uae_sem_wait (&gui_sem);
strncpy (changed_prefs.df[n], new_disk_string[n], 255);
changed_prefs.df[n][255] = '\0';
uae_sem_post (&gui_sem);
break;
case 2:
uae_reset ();
break;
case 3:
activate_debugger ();
break;
case 4:
uae_quit ();
break;
}
}
}